package cn.bigcontainer.alt.meta.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bigcontainer.alt.common.util.WoKit;
import cn.bigcontainer.alt.meta.dao.DbMetaDao;
import cn.bigcontainer.alt.meta.dto.MObjectDto;
import cn.bigcontainer.alt.meta.dto.MySqlColumn;
import cn.bigcontainer.alt.meta.mapper.MObjectMapper;
import cn.bigcontainer.alt.meta.po.MObject;
import cn.bigcontainer.alt.meta.po.MProperty;
import cn.bigcontainer.alt.meta.po.MRelation;
import cn.bigcontainer.alt.meta.service.DbMetaService;
import cn.bigcontainer.alt.meta.service.MetaService;

@Service
@Transactional
@Primary
public class DbMetaServiceImpl implements DbMetaService {

	@Resource
	private DbMetaDao databaseMetaDao;
	
	@Autowired
	private MetaService metaService;
	
	@Override
	public List<Map<String, Object>> getAllTables(String activeTable) {
		List<Map<String, Object>> tables = databaseMetaDao.queryAllTables();
		if (tables != null && tables.size() > 0) {
			if (activeTable != null && !activeTable.isEmpty()) {
				for (Map<String, Object> table : tables) {
					if (table.get("tablename").equals(activeTable)) {
						table.put("active", true);
					}
				}
			} else {
				tables.get(0).put("active", true);
			}
		}
		return tables;
	}
	
	
	@Override
	public List<MySqlColumn> getColumns(String table) {
		return databaseMetaDao.queryColumns(table);
	}

	private static String createPropertyId(String table, String columnName) {
		return (table + "_" + columnName).toLowerCase();
	}

	@Resource
	private MObjectMapper objectMapper;

	@Override
	public void updateMObjects(String table) {
		// 刪除元数据
		objectMapper.deleteById(table);
		MObject mObject = new MObject();
		mObject.setId(table);
		int idx = table.indexOf('_');
		mObject.setNo(table.substring(idx + 1));
		String tableComment = databaseMetaDao.queryTableComment(table);
		mObject.setName(WoKit.getString(tableComment, table));
		mObject.setIdx(0);
		mObject.setModule(table.split("_")[0]);
		mObject.setStatus(0);
		mObject.setProperties(new ArrayList<>());
		// 插入列元数据
		List<MySqlColumn> cols = databaseMetaDao.queryColumns(table);
		for (int i = 0; i < cols.size(); i ++) {
			MySqlColumn col = cols.get(i);
			MProperty property = new MProperty();
			property.setId(DbMetaServiceImpl.createPropertyId(table, col.getField()));
			property.setName(col.getField());
			property.setDescription(col.getDescription());
			property.setType(col.getLogicType());
			property.setTypeDetail(col.getTypeDetail());
			property.setKey(col.isPrimaryKey() ? 1 : 0);
			if (property.getKey() == 1) {
				mObject.setStatus(1);
			}
			property.setMandatory(col.isNull() ? 0 : 1);
			property.setDefaultValue(col.getDefaultValue());
			property.setIndex(i * 10);
			property.setUnique(0);
			mObject.getProperties().add(property);
		}
		// 插入表元数据
		objectMapper.insert(mObject);
		// 更新默认crud数据
		// metaService.createDefaultCrud(table);
	}

	private MRelation createRelation (MObject mObject, MObject relatedObject) {
		MRelation r = new MRelation();
		Integer anInt = mObject.getData().getInt(MObjectDto.PARAM_RELATION_NUM, -1) + 1;
		r.setId("r_" + mObject.getId() + "_" + anInt);
		r.setIndex(anInt);
		r.setRelatedName(mObject.getName());
		// r.setName(WoKit.getString(mProperty.getDescription(), relatedObject.getName()));
		r.setRelatedObjectId(relatedObject.getId());
		r.setRelatedIds(MObjectDto.getKeyIds(relatedObject));
		mObject.getRelations().add(r);
		mObject.getData().put(MObjectDto.PARAM_RELATION_NUM, anInt);
		return r;
	}

	@Override
	public void createRelationM21 (String table, String pk, String relatedTable) {
		MObject mObject = objectMapper.selectById(table);
		MProperty mProperty = MObjectDto.getPropertyByName(mObject, pk);
		MObject relatedObject = objectMapper.selectById(relatedTable);
		MRelation r = createRelation(mObject, relatedObject);
		r.setPropertyIds(MObjectDto.getPropertyByName(mObject, pk).getId());
		r.setType(MRelation.TYPE_M21);
		r.setName(WoKit.getString(mProperty.getDescription(), relatedObject.getName()));
		objectMapper.updateById(mObject);
	}

	@Override
	public void createRelationM2M (String table, String relationTable, String relationKey, String relationInverseKey, String relatedTable){
		MObject mObject = objectMapper.selectById(table);
		MObject relationObject = objectMapper.selectById(relationTable);
		MProperty relationProperty = MObjectDto.getPropertyByName(relationObject, relationKey);
		MProperty relationInverseProperty = MObjectDto.getPropertyByName(relationObject, relationInverseKey);
		MObject relatedObject = objectMapper.selectById(relatedTable);
		MRelation r = createRelation(mObject, relatedObject);
		r.setType(MRelation.TYPE_M2M);
		r.setName(WoKit.getString(relationObject.getName(), relatedObject.getName()));
		r.setPropertyIds(MObjectDto.getKeyIds(mObject));
		r.setRelationIds(relationProperty.getId());
		r.setRelationInverseIds(relationInverseProperty.getId());
		r.setRelationObjectId(relationObject.getId());
		objectMapper.updateById(mObject);
	}

}
